package ar.edu.utn.frre.sistop.simumem.fragments;

import java.util.ArrayList;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import ar.edu.utn.frre.sistop.simumem.DataLoadActivity;
import ar.edu.utn.frre.sistop.simumem.R;
import ar.edu.utn.frre.sistop.simumem.common.Preferences;
import ar.edu.utn.frre.sistop.simumem.model.Proceso;

public class ProcessLoadFragment extends Fragment {
	
	private ProcessAdapter mAdapter;
	private ArrayList<Proceso> mData;
	private LinearLayout mHeader;
	private ListView mProcesosListView;
	private EditText mIdProceso;
	private EditText mArribo;
	private EditText mIrrupcion;
	private EditText mTamano;
	private ImageView mAgregarProceso;
	private Preferences mPreferences;

	@Override
	public void onActivityCreated(@Nullable Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		getActivity().setTitle(R.string.titleDataLoad_Procesos);
		mPreferences = ((DataLoadActivity) getActivity()).getPreferences();
		
		if (mData == null) {
			mData = new ArrayList<Proceso>();
		}
		if (mAdapter == null) {
			mAdapter = new ProcessAdapter(getActivity(), mData);
		}

		obtenerHandlesDeVistas();
		mProcesosListView.setAdapter(mAdapter);
		mProcesosListView.setEmptyView(getActivity().findViewById(R.id.empty_list_processes));

		// agregar proceso
		mTamano.setOnEditorActionListener(new OnEditorActionListener() {
			@Override
			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				if (actionId == R.id.action_add_process || actionId == EditorInfo.IME_ACTION_DONE) {
					validaryAgregarProceso();
					return true;
				}
				return false;
			}
		});

		mAgregarProceso.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				validaryAgregarProceso();
			}
		});

		// remover proceso
		mProcesosListView.setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
				mData.remove(position);
				mAdapter.notifyDataSetChanged();
				checkHeaderVisibility();
				return true;
			}
		});
	}

	@Override
	public void onResume() {
		mIdProceso.requestFocus(); // while we're at it
		recuperarProcesos();
		checkHeaderVisibility();
		super.onResume();
	}

	@Override
	public void onPause() {
		guardarProcesos();
		super.onPause();
	}

	private void recuperarProcesos() {
		mData.clear();
		for (Proceso proceso : mPreferences.getProcesos()) {
			mData.add(proceso);
		}
		mAdapter.notifyDataSetChanged();
	}

	private void guardarProcesos() {
		mPreferences.setProcesos(mData);
	}
	
	public void checkHeaderVisibility() {
		if (mAdapter.getCount() == 0) {
			mHeader.setVisibility(View.GONE);
		} else {
			mHeader.setVisibility(View.VISIBLE);
		}
	}

	private void obtenerHandlesDeVistas() {
		mHeader = (LinearLayout) getActivity().findViewById(R.id.llDataLoadProcess_header);
		mProcesosListView = (ListView) getActivity().findViewById(R.id.list_processes);
		mIdProceso = (EditText) getActivity().findViewById(R.id.txtDataLoadProcess_id);
		mArribo = (EditText) getActivity().findViewById(R.id.txtDataLoadProcess_arrivalTime);
		mIrrupcion = (EditText) getActivity().findViewById(R.id.txtDataLoadProcess_burstTime);
		mTamano = (EditText) getActivity().findViewById(R.id.txtDataLoadProcess_size);
		mAgregarProceso = (ImageView) getActivity()
				.findViewById(R.id.imgDataLoadProcess_addProcess);
	}

	private void validaryAgregarProceso() {
		if (camposVacios(mIdProceso, mArribo, mIrrupcion, mTamano)) {
			Toast.makeText(getActivity(), R.string.toastIncompleteFields_Process,
					Toast.LENGTH_SHORT).show();
		} else if (!nuevoId()) {
			Toast.makeText(getActivity(), R.string.toastDuplicatedId_Process, Toast.LENGTH_SHORT)
					.show();
			mIdProceso.setText("");
			mIdProceso.requestFocus();
		} else if (Long.parseLong(mIrrupcion.getText().toString()) == 0) {
			Toast.makeText(getActivity(), R.string.toastZeroProcessBurstTime, Toast.LENGTH_SHORT)
					.show();
			mIrrupcion.setText("");
			mIrrupcion.requestFocus();
		} else if (Long.parseLong(mTamano.getText().toString()) == 0) {
			Toast.makeText(getActivity(), R.string.toastZeroProcessSize, Toast.LENGTH_SHORT).show();
			mTamano.setText("");
			mTamano.requestFocus();
		} else {
			agregarProceso();
		}
	}

	private boolean camposVacios(EditText... editTexts) {
		for (EditText editText : editTexts) {
			if (TextUtils.isEmpty(editText.getText()))
				return true;
		}
		return false;
	}

	private boolean nuevoId() {
		long id = Long.parseLong(mIdProceso.getText().toString());
		for (Proceso proceso : mData) {
			if (proceso.getId() == id)
				return false;
		}
		return true;
	}

	private void agregarProceso() {
		Proceso proceso = new Proceso();
		proceso.setId(Long.parseLong(mIdProceso.getText().toString()));
		proceso.setArribo(Long.parseLong(mArribo.getText().toString()));
		proceso.setIrrupcion(Long.parseLong(mIrrupcion.getText().toString()));
		proceso.setTamano(Long.parseLong(mTamano.getText().toString()));
		mIdProceso.setText(String.valueOf(Long.parseLong(mIdProceso.getText().toString()) + 1));
		mArribo.setText("");
		mIrrupcion.setText("");
		mTamano.setText("");
		mData.add(proceso);
		mAdapter.notifyDataSetChanged();
		if (mAdapter.getCount() == 1) {
			mHeader.setVisibility(View.VISIBLE);
		}
		mProcesosListView.post(new Runnable() {
			@Override
			public void run() {
				mProcesosListView.setSelection(mAdapter.getCount() - 1);
				mArribo.requestFocus();
			}
		});
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragment_data_load_process, container, false);
		return rootView;
	}

	public ArrayList<Proceso> getProcesos() {
		return mData;
	}
}